home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / out-of-phase-102-c / OutOfPhase 1.02 Source / OutOfPhase Folder / Level 1 Extensions 29Sep94 / SimpleButton.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  7.6 KB  |  258 lines  |  [TEXT/KAHL]

  1. /* SimpleButton.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    System Dependency Library for Building Portable Software               */
  5. /*    Macintosh Version                                                      */
  6. /*    Written by Thomas R. Lawrence, 1993 - 1994.                            */
  7. /*                                                                           */
  8. /*    This file is Public Domain; it may be used for any purpose whatsoever  */
  9. /*    without restriction.                                                   */
  10. /*                                                                           */
  11. /*    This package is distributed in the hope that it will be useful,        */
  12. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  13. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                   */
  14. /*                                                                           */
  15. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  16. /*                                                                           */
  17. /*****************************************************************************/
  18.  
  19. #include "MiscInfo.h"
  20. #include "Audit.h"
  21. #include "Debug.h"
  22. #include "Definitions.h"
  23.  
  24. #include "SimpleButton.h"
  25. #include "Screen.h"
  26. #include "Memory.h"
  27. #include "EventLoop.h"
  28. #include "DataMunging.h"
  29.  
  30.  
  31. struct SimpleButtonRec
  32.     {
  33.         WinType*            Window;
  34.         char*                    Name;
  35.         OrdType                X;
  36.         OrdType                Y;
  37.         OrdType                Width;
  38.         OrdType                Height;
  39.         MyBoolean            Default;
  40.     };
  41.  
  42.  
  43. /* allocate the simple button */
  44. SimpleButtonRec*        NewSimpleButton(WinType* Window, char* Name,
  45.                                             OrdType X, OrdType Y, OrdType Width, OrdType Height)
  46.     {
  47.         SimpleButtonRec*        TheButton;
  48.         char*                                NameTemp;
  49.         long                                Scan;
  50.         long                                Index;
  51.  
  52.         TheButton = (SimpleButtonRec*)AllocPtrCanFail(
  53.             sizeof(SimpleButtonRec),"SimpleButton");
  54.         if (TheButton == NIL)
  55.             {
  56.                 return NIL;
  57.             }
  58.         TheButton->Window = Window;
  59.         Scan = 0;
  60.         while (Name[Scan] != 0)
  61.             {
  62.                 Scan += 1;
  63.             }
  64.         NameTemp = AllocPtrCanFail(Scan + 1,"SimpleButtonName");
  65.         if (NameTemp == NIL)
  66.             {
  67.                 ReleasePtr((char*)TheButton);
  68.                 return NIL;
  69.             }
  70.         for (Index = 0; Index <= Scan; Index += 1)
  71.             {
  72.                 NameTemp[Index] = Name[Index];
  73.             }
  74.         TheButton->Name = NameTemp;
  75.         TheButton->X = X;
  76.         TheButton->Y = Y;
  77.         TheButton->Width = Width;
  78.         TheButton->Height = Height;
  79.         TheButton->Default = False;
  80.         return TheButton;
  81.     }
  82.  
  83.  
  84. /* dispose of the button and internal data */
  85. void                                DisposeSimpleButton(SimpleButtonRec* TheButton)
  86.     {
  87.         ReleasePtr(TheButton->Name);
  88.         ReleasePtr((char*)TheButton);
  89.     }
  90.  
  91.  
  92. /* indicate whether this button is a default button or not.  if it is, it will */
  93. /* be hilighted specially (heavy outline).  It will NOT be drawn though */
  94. void                                SetDefaultButtonState(SimpleButtonRec* TheButton, MyBoolean Default)
  95.     {
  96.         CheckPtrExistence(TheButton);
  97.         TheButton->Default = Default;
  98.     }
  99.  
  100.  
  101. /* find out where the button is located */
  102. OrdType                            GetSimpleButtonXLoc(SimpleButtonRec* TheButton)
  103.     {
  104.         CheckPtrExistence(TheButton);
  105.         return TheButton->X;
  106.     }
  107.  
  108.  
  109. /* find out where the button is located */
  110. OrdType                            GetSimpleButtonYLoc(SimpleButtonRec* TheButton)
  111.     {
  112.         CheckPtrExistence(TheButton);
  113.         return TheButton->Y;
  114.     }
  115.  
  116.  
  117. /* find out where the button is located */
  118. OrdType                            GetSimpleButtonWidth(SimpleButtonRec* TheButton)
  119.     {
  120.         CheckPtrExistence(TheButton);
  121.         return TheButton->Width;
  122.     }
  123.  
  124.  
  125. /* find out where the button is located */
  126. OrdType                            GetSimpleButtonHeight(SimpleButtonRec* TheButton)
  127.     {
  128.         CheckPtrExistence(TheButton);
  129.         return TheButton->Height;
  130.     }
  131.  
  132.  
  133. /* change the location of the button */
  134. void                                SetSimpleButtonLocation(SimpleButtonRec* TheButton,
  135.                                             OrdType X, OrdType Y, OrdType Width, OrdType Height)
  136.     {
  137.         CheckPtrExistence(TheButton);
  138.         TheButton->X = X;
  139.         TheButton->Y = Y;
  140.         TheButton->Width = Width;
  141.         TheButton->Height = Height;
  142.     }
  143.  
  144.  
  145. /* internal routine for drawing button */
  146. static void                    InternalRedrawButton(SimpleButtonRec* TheButton, MyBoolean Hilited)
  147.     {
  148.         OrdType        TextStartX;
  149.         OrdType        TextStartY;
  150.  
  151.         CheckPtrExistence(TheButton);
  152.         SetClipRect(TheButton->Window,TheButton->X - 4,TheButton->Y - 4,
  153.             TheButton->Width + 4 + 4,TheButton->Height + 4 + 4);
  154.         TextStartX = (TheButton->Width - LengthOfText(GetUglyFont(),12,
  155.         TheButton->Name,StrLen(TheButton->Name),ePlain)) / 2 + TheButton->X;
  156.         TextStartY = (TheButton->Height - GetFontHeight(GetUglyFont(),12)) / 2
  157.             + TheButton->Y;
  158.         if (Hilited)
  159.             {
  160.                 DrawRoundBoxPaint(TheButton->Window,eBlack,TheButton->X,TheButton->Y,
  161.                     TheButton->Width,TheButton->Height,10,10);
  162.                 InvertedTextLine(TheButton->Window,GetUglyFont(),12,TheButton->Name,
  163.                     StrLen(TheButton->Name),TextStartX,TextStartY,ePlain);
  164.             }
  165.          else
  166.             {
  167.                 DrawRoundBoxErase(TheButton->Window,TheButton->X,TheButton->Y,
  168.                     TheButton->Width,TheButton->Height,10,10);
  169.                 DrawTextLine(TheButton->Window,GetUglyFont(),12,TheButton->Name,
  170.                     StrLen(TheButton->Name),TextStartX,TextStartY,ePlain);
  171.             }
  172.         DrawRoundBoxFrame(TheButton->Window,eBlack,TheButton->X,TheButton->Y,
  173.             TheButton->Width,TheButton->Height,10,10);
  174.         if (TheButton->Default)
  175.             {
  176.                 DrawRoundBoxFrame(TheButton->Window,eBlack,
  177.                     TheButton->X - 2,TheButton->Y - 2,
  178.                     TheButton->Width + (2 * 2),
  179.                     TheButton->Height + (2 * 2),12,12);
  180.                 DrawRoundBoxFrame(TheButton->Window,eBlack,
  181.                     TheButton->X - 3,TheButton->Y - 3,
  182.                     TheButton->Width + (2 * 3),
  183.                     TheButton->Height + (2 * 3),12,12);
  184.                 DrawRoundBoxFrame(TheButton->Window,eBlack,
  185.                     TheButton->X - 3 - 1,TheButton->Y - 3,
  186.                     TheButton->Width + (2 * 3),
  187.                     TheButton->Height + (2 * 3),12,12);
  188.                 DrawRoundBoxFrame(TheButton->Window,eBlack,
  189.                     TheButton->X - 3 + 1,TheButton->Y - 3,
  190.                     TheButton->Width + (2 * 3),
  191.                     TheButton->Height + (2 * 3),12,12);
  192.                 DrawRoundBoxFrame(TheButton->Window,eBlack,
  193.                     TheButton->X - 4,TheButton->Y - 4,
  194.                     TheButton->Width + (2 * 4),
  195.                     TheButton->Height + (2 * 4),12,12);
  196.             }
  197.     }
  198.  
  199.  
  200. /* do a full redraw of the button */
  201. void                                RedrawSimpleButton(SimpleButtonRec* TheButton)
  202.     {
  203.         InternalRedrawButton(TheButton,False);
  204.     }
  205.  
  206.  
  207. /* do a mouse down in the button.  if Tracking != NIL, then it will be repeatedly */
  208. /* called with the Inside status until the mouse goes up */
  209. MyBoolean                        SimpleButtonMouseDown(SimpleButtonRec* TheButton, OrdType X, OrdType Y,
  210.                                             void (*Tracking)(void* Refcon, MyBoolean Inside), void* Refcon)
  211.     {
  212.         MyBoolean                Inside;
  213.         MyBoolean                OldInside;
  214.  
  215.         OldInside = False;
  216.         do
  217.             {
  218.                 Inside = SimpleButtonHitTest(TheButton,X,Y);
  219.                 if (OldInside != Inside)
  220.                     {
  221.                         InternalRedrawButton(TheButton,Inside);
  222.                         OldInside = Inside;
  223.                     }
  224.                 if (Tracking != NIL)
  225.                     {
  226.                         (*Tracking)(Refcon,Inside);
  227.                     }
  228.             } while (GetAnEvent(&X,&Y,NIL,NIL,NIL,NIL) != eMouseUp);
  229.         InternalRedrawButton(TheButton,False);
  230.         return Inside;
  231.     }
  232.  
  233.  
  234. /* momentarily flash the button.  this is used to provide visual feedback in case */
  235. /* a key press performs the same function as clicking the button. */
  236. void                                FlashButton(SimpleButtonRec* TheButton)
  237.     {
  238.         double                        EntryTime;
  239.  
  240.         InternalRedrawButton(TheButton,True);
  241.         EntryTime = ReadTimer();
  242.         while (TimerDifference(ReadTimer(),EntryTime) < 0.1)
  243.             {
  244.                 RelinquishCPUCheckCancel();
  245.             }
  246.         InternalRedrawButton(TheButton,False);
  247.     }
  248.  
  249.  
  250. /* find out if the specified location is within the button box */
  251. MyBoolean                        SimpleButtonHitTest(SimpleButtonRec* TheButton, OrdType X,
  252.                                             OrdType Y)
  253.     {
  254.         return (X >= TheButton->X) && (Y >= TheButton->Y)
  255.             && (X < TheButton->X + TheButton->Width)
  256.             && (Y < TheButton->Y + TheButton->Height);
  257.     }
  258.